﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SaturniLibrary.MIGS.V1
{
    public class ThreePartyResponse : SortedDictionary<string, string>
    {
        public string SecureHash { get; set; }

        public string SecureSecret { get; set; }

        public ThreePartyResponse() : base(StringComparer.Ordinal)
        {
            
        }

        public string ToDataString()
        {
            return string.Format("{{SecureSecret={0},{1}}}", SecureSecret, string.Join(",", this.Select(kv => kv.Key.ToString() + "=" + kv.Value.ToString()).ToArray()));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="responseUrl">responseUrl can be a querystring or absolute url</param>
        public void FromResponseUrl(string responseUrl)
        {
            if (string.IsNullOrWhiteSpace(responseUrl))
            {
                throw new ArgumentNullException("responseUrl");
            }
            string query = string.Empty;
            if (responseUrl.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || responseUrl.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
            {
                var uri = new Uri(responseUrl);
                query = uri.Query;
            }
            else if(responseUrl.Contains("?"))
            {
                int pos = responseUrl.IndexOf("?");
                query = responseUrl.Substring(pos + 1);
            }
            else
            {
                query = responseUrl;
            }

            var fieldArray = query.Split('&');

            foreach (string pair in fieldArray)
            {
                var keyvalue = pair.Split('=');
                if (keyvalue.Length > 1)
                {
                    if (string.Compare("vpc_SecureHash", keyvalue[0]) == 0)
                    {
                        SecureHash = keyvalue[1];
                    }
                    else
                    {
                        this.Add(keyvalue[0], keyvalue[1]);    
                    }
                }
            }
        }

        private void ValidateSecureHash()
        {
            if (!string.IsNullOrWhiteSpace(SecureSecret) && this.ContainsKey("vpc_SecureHash") && !string.IsNullOrWhiteSpace(this["vpc_SecureHash"]))
            {
                var secureHashFromUrl = MIGSHelper.GetSearchHash(SecureSecret, this);
                if (secureHashFromUrl != SecureHash)
                {
                    throw new Exception("SecureHash Validate Faild");
                }
            }
        }

        private void Validate()
        {
            if (!this.ContainsKey("vpc_version"))
            {
                throw new Exception("version is required");
            }

            if (this["vpc_Version"] != "1")
            {
                throw new Exception("MIGS version error, the value must be 1");
            }

            if (!this.ContainsKey("vpc_Command"))
            {
                throw new Exception("Command is required");
            }

            if (string.Compare(this["vpc_Command"], "pay", StringComparison.OrdinalIgnoreCase) != 0)
            {
                throw new Exception("Command must be set to 'pay'");
            }

            if (!this.ContainsKey("vpc_MerchTxnRef"))
            {
                throw new Exception("MerchTxnRef is required");
            }

            if (!this.ContainsKey("vpc_Merchant"))
            {
                throw new Exception("Merchant is required");
            }

            if (!this.ContainsKey("vpc_Amount"))
            {
                throw new Exception("Amount is required");
            }
            try
            {
                int.Parse(this["amount"]);
            }
            catch
            {
                throw new Exception("Amount must be integer type");
            }

            if (!this.ContainsKey("vpc_Locale"))
            {
                throw new Exception("Locale is required");
            }

            if (!this.ContainsKey("vpc_TxnResponseCode"))
            {
                throw new Exception("TxnResponseCode is required");
            }

            if (!this.ContainsKey("vpc_TransactionNo"))
            {
                throw new Exception("TransactionNo is required");
            }

            ValidateSecureHash();
        }


    }
}
